//
//  GameVC.m
//  Mockup
//
//  Created by Bernardo Quibiana on 2/20/10.
//  Copyright 2010 Mac-Easy@USC. All rights reserved.
//


/**
 Fixed bug where you couldn't star a new game after you'd unloaded the first (firstResponder issue). This also seemed to fix the problem where the debugger would "hang".
 Timer now pauses correctly when the play is anywhere but the game board. 
 Problem: timefr still "carries over" the count value from one game to another new one. Either it's not invalidating correctly or the "count" value isn't changing. 
 **/

#import "GameVC.h"
#import "Sound.h"

@implementation GameVC

//Back-end sythesized properties
@synthesize board;
@synthesize difficulty;
@synthesize gameState;
@synthesize initialTouchPos;
@synthesize score;

//Timer properties
@synthesize myCounterLabel;
@synthesize myTimer;
@synthesize readyTimer;

//Menu and text properties
@synthesize acceptable;
@synthesize myTextField;
@synthesize userName;

@synthesize scoreLabel;

//Timer counters
static int count = TIMERVALUE;
static int ready = READYVALUE;

- (void)updateCounter:(NSTimer *)theTimer {
	
	if (timerIsCountingDown == TRUE){ 
		//printf("%d...\n", count);
		count = (count < 1) ? 0 : count - 1;
	}
	
	NSString *s = [NSString stringWithFormat:@"Time left: %d", count];
	self.myCounterLabel.text = s;
	
	if(count <= 10 && !emptyBoard) {
		NSString *s = [NSString stringWithFormat:@"Time left: %d", count];
		self.myCounterLabel.text = s;
		self.myCounterLabel.textColor= [UIColor redColor];	
		self.myCounterLabel.font = [UIFont boldSystemFontOfSize:20];
		
		if(count % 2 == 0 || count <= 3){
			[Sound soundEffect:8];
		}
	}
	
	if(count == 0|| emptyBoard){
		[Sound soundEffect:10];
		[self stopTimer:theTimer];
		[self endGame];
		//-(NSInteger) checkHighScoreForDifficulty:(difficulty_t) difficulty withScore:(NSInteger) score;
		//-(BOOL) updateHighScoresForDifficulty: (difficulty_t) difficulty withName:(NSString *)username andScore: (NSInteger) score;
	}
}

//Timer for "Get ready" sequence on the game loading.
-(void)updateReady:(NSTimer *)theTimer /**onCount:(int)_count**/{
	printf("Break...\n");
	if (timerIsCountingDown == TRUE){ 
		printf("%d...\n", ready);
		ready = (ready < 1) ? 0 : ready - 1;
	}
	printf("Break...\n");
	switch (ready) {
		case 5:
			readyImage_1.image = [UIImage imageNamed:@"ready1.png"];
			break;
		case 4:
			readyImage_1.image = [UIImage imageNamed:@"G1.Red.png"];
			[Sound soundEffect:8];
			break;
		case 3:
			readyImage_2.image = [UIImage imageNamed:@"G2.Yellow.png"];
			[Sound soundEffect:8];
			break;
		case 2:
			readyImage_3.image = [UIImage imageNamed:@"G4.Green.png"];
			[Sound soundEffect:8];
			break;
			
		case 1:
			readyImage_1.image = [UIImage imageNamed:@"GoDogGo_small.png"];
			[Sound soundEffect:10];
			break;
			
		case 0:
			[self stopTimer:theTimer];
			readyImage_1.image = NULL;
			[readyImage_1 release];
			readyImage_2.image = NULL;
			[readyImage_2 release];
			readyImage_3.image = NULL;
			[readyImage_3 release];
			[self stopTimer:myTimer];
			[self setUpCountTimer:myTimer];
			[self.board loadTilesToView: self.view];
			self.gameState = Running;
			break;
		default:
			break;
	}
}

/**TEXT METHODS**/
- (BOOL) textField:(UITextField*)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString*)textEntered {
	
	NSCharacterSet *myCharSet = [NSCharacterSet characterSetWithCharactersInString:@"~`!@#$%^&*()_-+={}[]|\\:\";'<>?/.,"];
   	
	for (int i = 0; i < [textEntered length]; i++) {
        unichar c = [textEntered characterAtIndex:i];
        if ([myCharSet characterIsMember:c]) {
            return NO;
        }
    }
    return YES;
}

- (BOOL)textFieldShouldReturn:(UITextField *)textField {
	[textField resignFirstResponder];
	return YES;
}
- (BOOL)textFieldShouldEndEditing:(UITextField *)textField {
	if(!([textField.text length])>=10) {
		return NO;
	}
	
	return YES;
}

- (void)textFieldDidEndEditing:(UITextField *)textField {
	NSLog(@"got here");
	
	
	if([textField.text length]>0&&[textField.text length]<=10){
		acceptable=textField.text;
		
		
	}else{
		
				[self getUserNameErrorMSG:YES];
		
	}
	if(acceptable!=nil){
		[self stringForHS:YES];
		
	}
}

-(id) initWithDifficulty:(difficulty_t) _difficulty{
	if (self = [super init]) {
		int level;
		switch (_difficulty) {
			case Easy:
				level = 5;
				break;
			case Medium:
				level = 6;
				break;
			case Hard:
				level = 8;
				break;
			default:
				level = 5;	// should not happen! Error response needed
				break;
		}
		
		Board * _board = [[Board alloc] initWithRandomMatrix:level];
		self.board = _board;
		[_board release];
		
		self.difficulty = _difficulty;
		self.gameState = Starting;
		emptyBoard = NO;
	}
	return self;
}

-(id) initWithContentOfFile:(NSString *)filename {
	if (self = [super init]) {
		Board * _board = [[Board alloc] initWithContentOfFile:filename];
		self.board = _board;
		[_board release];
		
		self.difficulty = [board getDifficultyLevel];
		self.gameState = Starting;
		score = self.board.score;
		emptyBoard = NO;
	}
	return self;
}

-(void)setUpCountTimer:(NSTimer *)theTimer {
	count = (self.board.time != 0) ? self.board.time : TIMERVALUE;
	
	timerIsCountingDown = TRUE;
	
	[NSTimer scheduledTimerWithTimeInterval:1.0f
									 target:self
								   selector:@selector(updateCounter:)
								   userInfo:nil
									repeats:YES];
}

-(void)setUpReadyTimer:(NSTimer *)theTimer {
	
	ready = READYVALUE;
	
	timerIsCountingDown = TRUE;
	[NSTimer scheduledTimerWithTimeInterval:1.0f
									 target:self
								   selector:@selector(updateReady:)
								   userInfo:nil
									repeats:YES];
	
}

-(void)stopTimer:(NSTimer *)theTimer {
	printf("Stopping timer...");
	if (theTimer != nil) {
		[theTimer invalidate];
		theTimer = nil;
	}
}


/*
 // The designated initializer.  Override if you create the controller programmatically and want to perform customization that is not appropriate for viewDidLoad.
 - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
 if (self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]) {
 // Custom initialization
 }
 return self;
 }
 */


// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
	printf("View loaded...\n");
	[super viewDidLoad];
	
	self.wantsFullScreenLayout =  YES;
	[self.view setBackgroundColor: [UIColor blackColor]];
	self.view.frame = [UIScreen mainScreen].applicationFrame;
	
	self.scoreLabel.text = [NSString stringWithFormat:@"%d", score];
	self.myCounterLabel.text = @"Starting...";
	[self stopTimer:readyTimer];
	[self setUpReadyTimer:readyTimer];
}

- (void)viewDidAppear:(BOOL)animated {
	[self becomeFirstResponder];
	[super viewDidAppear:animated];
	
	if (self.gameState == Paused) {
		[self showPauseMenu];
		[self becomeFirstResponder];
	} else if(self.gameState == Over) {
		[self stopTimer:myTimer];
		[self resignFirstResponder];
		
		[NSTimer scheduledTimerWithTimeInterval:0.0f
										 target:self
									   selector:@selector(quit)
									   userInfo:nil
										repeats:NO];
	}
}

- (void)viewWillDisappear:(BOOL)animated{
	BOOL savedGame;
	if (self.gameState == Running || self.gameState == Paused) {
		printf("View will disappear while still running/paused...\n");
		self.board.score = self.score;
		self.board.time = (count < TIMERVALUE) ? count + 1: TIMERVALUE;
		savedGame = [self.board saveGame];
		[Configuration didSaveGame:savedGame];
		if (savedGame) {
			NSLog(@"Successfully saved game");
		}
	}
	
}
- (void)viewDidUnload {
	// Release any retained subviews of the main view.
	// e.g. self.myOutlet = nil;
	
	
	self.board = nil;
	
	[self stopTimer:myTimer];
	//[myTimer invalidate];
	//myTimer = nil;
}

-(void) quit {
	[self dismissModalViewControllerAnimated:YES];
}
/*
 // Override to allow orientations other than the default portrait orientation.
 - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
 // Return YES for supported orientations
 return (interfaceOrientation == UIInterfaceOrientationPortrait);
 }
 */

- (void)didReceiveMemoryWarning {
	// Releases the view if it doesn't have a superview.
    [super didReceiveMemoryWarning];
	
	// Release any cached data, images, etc that aren't in use.
}


-(IBAction) ScoreButtonPressed:(id)sender {
	self.gameState = Paused;
	[self showPauseMenu];
}

-(void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
	if (self.gameState == Running && self.board.state == Idle) {
		initialTouchPos = [[touches anyObject] locationInView: self.view]; 
	}
}

-(void) touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event{
	if (self.gameState == Running && self.board.state == Idle) {
		[self.board handleTouchFrom:initialTouchPos 
								 to:[[touches anyObject] locationInView: self.view]];
		initialTouchPos = [[touches anyObject] locationInView: self.view]; 
	}
}

-(void) touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{
	if (self.gameState == Running) {
		initialTouchPos = [[touches anyObject] locationInView: self.view];
		[self.view setUserInteractionEnabled:NO];
		[self.board resetCurDirection];
		//[self.board updateTilesPosition];
		[self.board adjustTilesPosition];
		[self.board animateTilesFall];
		
		 NSInteger timer = kBoardMatchDuration;
		[NSTimer scheduledTimerWithTimeInterval:timer target:self 
									   selector:@selector(matchBoard:) 
									   userInfo:nil repeats:YES];
	}
}

-(void) touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event{
	if (self.gameState == Running) {
		initialTouchPos = [[touches anyObject] locationInView: self.view];
		[self.board resetCurDirection];
	}
}

//Shake code, baby!
- (void) motionEnded:(UIEventSubtype)motion withEvent:(UIEvent *)event{
	printf("Shake!\n");
	if(event.subtype ==UIEventSubtypeMotionShake){
		//Do the falling blocks call to the Board
		[self.board generateNewTiles];
		[self.board switchEmptyTiles];
		//[self.board matchTiles];
		[self.board matchTilesFast];
	}
	if([super respondsToSelector:@selector(motionEnded:withEvent:)]){
		[super motionEnded:motion withEvent:event];
	}
}


-(void) matchBoard:(NSTimer *)theTimer{
	if ([theTimer isValid]) {
		NSInteger addScore;
		// call board for matching, get score
		printf("Matching tiles...\n");
		
		addScore = [self.board matchTiles];
		printf("Player made score: %d \n", addScore);
		
		score = addScore + score;
		printf("Added scores: %d \n", score);
		
		NSString *scoreString = [NSString stringWithFormat:@"%d", score];
		
		self.scoreLabel.text = scoreString;
		
		if (addScore == 0) {
			[theTimer invalidate];
			//[self.view setUserInteractionEnabled:YES];
//*
			NSInteger timer = kInputLagDuration;
			[NSTimer scheduledTimerWithTimeInterval:timer target:self 
										   selector:@selector(readyForInput:) 
										   userInfo:nil repeats:NO];
 //*/
		} else if ([self.board isEmpty]) {
			emptyBoard = YES;	// timer will be invalided on next firing
			timerIsCountingDown = NO;
	
			// bonus score???
			score += 300;
			scoreString = [NSString stringWithFormat:@"%d", score];
			self.scoreLabel.text = scoreString;
			// sound effect??
			
		} 
	}
}

-(void) readyForInput:(NSTimer *)theTimer {
	[self.view setUserInteractionEnabled:YES];
}

-(void)endGame{
	self.gameState = Stopping;
	[Configuration didSaveGame:NO];
	if([[Configuration sharedInstance] checkHighScoreForDifficulty:difficulty withScore:score] >= 0){
		printf("User has made a high score");
		[self showEndGameAlert:TRUE];
		//Take the player to the High Score menu to show the score
	}else{
		printf("User has not made a high score");
		[self showEndGameAlert:FALSE];
	}
	self.gameState = Over;
}

-(BOOL) checkForHighScore{
	return TRUE;
}

- (BOOL)canBecomeFirstResponder{
	return YES;
}

- (BOOL)canResignFirstResponder{
	return YES;
}

-(void) saveAndQuit:(BOOL)save {
	self.gameState = Stopping;
	// save ?
	if (save) {
		[Configuration didSaveGame:[self.board saveGame]];
	} else {
		[Configuration didSaveGame:NO];
	}
	
	
	// quit preparations
	
	// quit
	[self dismissModalViewControllerAnimated:YES];
}

-(void) showEndGameAlert:(BOOL)didMakeHighScore{
	
	if(didMakeHighScore == TRUE){
		UIAlertView * endGameView = [[UIAlertView alloc] initWithTitle:@"Congratulations!" 
															   message:@"You made a HIGH SCORE!"
															  delegate:self cancelButtonTitle:@"Hooray!"
													 otherButtonTitles: nil];
		
		[endGameView setTag: NewHighScoreAlert];
		[endGameView show];
		[endGameView release];
		
	}else{
		UIAlertView * endGameView = [[UIAlertView alloc] initWithTitle:@"Good Game!" 
															   message:@"... but it wasn't good enough to be a HIGH SCORE." 
															  delegate:self cancelButtonTitle: nil
													 otherButtonTitles:@"Main Menu.", nil];
		[endGameView setTag: NonHighScoreAlert];
		[endGameView show];
		[endGameView release];
	}
	self.gameState = Over;
}

-(void) showPauseMenu {
	timerIsCountingDown = FALSE;
	[Sound soundEffect:2];
	UIAlertView * pauseView = [[UIAlertView alloc] initWithTitle:@"Game Paused" 
														 message:@"" 
														delegate:self cancelButtonTitle: nil
											   otherButtonTitles:@"Resume", @"Save", @"Help", 
							   @"High Scores", @"Options", @"Quit", nil];
	[pauseView setTag: PauseMenu];
	[pauseView setBackgroundColor: [UIColor blackColor]];
	//self.view.frame = [UIScreen mainScreen].applicationFrame;
	pauseView.frame = [UIScreen mainScreen].applicationFrame;
	[pauseView show];
	[pauseView release];
}

-(void) showQuitConfirmation {
	UIAlertView * quitAlert = [[UIAlertView alloc] initWithTitle:@"Quit the game" 
														 message:@"Are you sure you want to quit the game?" 
														delegate:self cancelButtonTitle:@"Cancel" 
											   otherButtonTitles:@"Save and quit", @"Quit", nil];
	[quitAlert setTag: QuitConfirmation];
	[quitAlert show];
	[quitAlert release];
}

-(void) showOptions {
	OptionsVC * optionsVC = [[OptionsVC alloc] initWithNibName:nil bundle:nil];
	[self presentModalViewController: optionsVC animated:YES];
	[optionsVC release];
}

-(void) showHelp {
	HelpVC * helpVC = [[HelpVC alloc] initWithNibName:nil bundle:nil];
	[self presentModalViewController:helpVC animated:YES];
	[helpVC release];
}

-(void) showHighScores {
	HighScoresVC * scoresVC = [[HighScoresVC alloc] initWithNibName:nil bundle:nil];
	[self presentModalViewController:scoresVC animated:YES];
	[scoresVC release];
}

-(void) alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
	if ([alertView tag] == PauseMenu) {
		// pause menu
		switch (buttonIndex) {
			case 0:		// resume
				self.gameState = Running;
				timerIsCountingDown = TRUE;
				[Sound soundEffect:3];
				break;
			case 1:		// save
				[self showPauseMenu];
				break;
			case 2:		// help
				[self showHelp];
				break;
			case 3:		// high scores
				[self showHighScores];
				break;
			case 4:		// options
				[self showOptions];
				break;
			case 5:		//	quit
				[self showQuitConfirmation];
				break;
			default:
				break;
		}
	} else if ([alertView tag] == QuitConfirmation) {
		// quit confirmation
		switch (buttonIndex) {
			case 0:		// cancel
				[self showPauseMenu];
				break;
			case 1:		// save and quit
				[self stopTimer:myTimer];
				[self resignFirstResponder];
				[self saveAndQuit:YES];
				break; 
			case 2:		// quit
				[self stopTimer:myTimer];
				[self resignFirstResponder];
				[self saveAndQuit:NO];
				break;
			default:
				[self saveAndQuit: NO];
		}
	}else if ([alertView tag] == NewHighScoreAlert) {
		//
		if(buttonIndex==0) {
			
		[self getUserName:YES];}
				
		
	}else if ([alertView tag] == NonHighScoreAlert) {
		//
		switch (buttonIndex) {
			case 0:		// try again (work in progress)
				//[self stopTimer:myTimer];
				//[self resignFirstResponder];
				//break;
			case 1:		// go back to the main menu
								//break;
			default:
				[self stopTimer:myTimer];
				[self resignFirstResponder];
				[self saveAndQuit:NO];
				break;
		}
	}else if([alertView tag] == UnamePrompt){
		 
		if((buttonIndex==0)&&(userName==nil)){
			[self getUserName:YES];
		} else{
			switch (buttonIndex) {
				case 0: //"Submit"
					[self resignFirstResponder];
					[self showHighScores];
					//[self saveAndQuit:NO];
					break;
				default:
					//[self saveAndQuit:NO];
					break;
			}
		}
	}
}

-(void) getUserName:(BOOL)uName{
	UIAlertView * alert = [[UIAlertView alloc] initWithTitle:@"Enter Name Here"	message:@"\nEntering a name into high scores:\n1. Enter Name\n 2. Press Return\n  3. Press Submit"	delegate:self cancelButtonTitle:@"Submit" otherButtonTitles:nil, nil];
	myTextField = [[UITextField alloc] initWithFrame:CGRectMake(12, 45, 260, 25)];
	myTextField.delegate = self;
	[alert setTag: UnamePrompt];
	[myTextField setBackgroundColor:[UIColor whiteColor]];
	[myTextField setKeyboardType:UIKeyboardTypeNamePhonePad];
	
	[alert addSubview:myTextField];
	[alert show];
	
	[alert release];
	[myTextField release];
}

-(NSString*)stringForHS:(BOOL)strReady{
	if(acceptable!=nil){
		userName= acceptable;
	}		
	NSLog(@"this is userName now: %@", userName);
	[[Configuration sharedInstance] updateHighScoresForDifficulty:difficulty withName:userName andScore:score];
	return userName;
}

-(void) getUserNameErrorMSG:(BOOL)uName{
	UIAlertView * alertB = [[UIAlertView alloc] initWithTitle:@"Error"	message:@"\nPlease enter a name with ten characters or less."	delegate:self cancelButtonTitle:@"Dismiss" otherButtonTitles:nil, nil];
	
	[alertB setTag: UnameErrorAlert];
	[alertB show];
	
	[alertB release];
	
	
	NSLog(@"this is acceptable now: %@", acceptable);
}

- (void)dealloc {
    [self.board release];
	[super dealloc];
}

@end
